/*
 * iSnakeClient.java
 *
 * Created on December 19, 2006, 6:56 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package net.sf.iSnake.core;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Calendar;
import javax.swing.*;
import net.sf.iSnake.UI.MainMenuPanel;
import net.sf.iSnake.UI.MultiplayerClientModePanel;
import net.sf.iSnake.UI.MultiplayerServerModePanel;
import net.sf.iSnake.UI.StandaloneModePanel;

import net.sf.iSnake.UI.iSnakeIntroductionPanel;
import net.sf.iSnake.configuration.iSnakeConfiguration;
import net.sf.iSnake.debug.GameDebugPanel;
import net.sf.iSnake.server.ServerCorePre;

/**
 *
 * @author thelinuxmaniac
 * @TODO Do something to remove the title "Java Application Window" when running this application with JWS in Linux (output is wiered in linux)
 * @TODO Prepare Documentation (apart from the JavaDoc) on "iSnake" about the working of this application( Docs. hold points in Locus)
 */
public class iSnakeClient extends JFrame implements ActionListener  {
    
    private ClassLoader classLoader;        // ClassLoader which is required to access local resources in JWS
    private static iSnakeConfiguration conf; // Stores the configurations for iSnakeClient application
    
    private GameController gameController;  // Game controller reference , required to start the server
    private MultiplayerClientModePanel mcmp;
    private StandaloneModePanel smp;
    private GameDebugPanel gd;
    private MultiplayerServerModePanel msmp;
    
    private KeyboardInputHandler localPlayerKeyboardInputHandler;   // Keylistener class that will capture local keystrokes to control local player's snake
    
    private JPanel gameContentsPanel;       // Panel that stretches all over the frame
    private JPanel buttonPanel;             // Panel that stretches all over the frame
    private CardLayout cardManager;
    private String[] MainMenuPanelActionCommandStrings;
    
    /** Creates a new instance of iSnakeClient */
    public iSnakeClient()   {
        Container c = getContentPane();
        c.setLayout(new BorderLayout());

        classLoader = this.getClass().getClassLoader();
        conf = new iSnakeConfiguration(classLoader);
        
        gameContentsPanel = new JPanel();
        cardManager = new CardLayout();
        gameContentsPanel.setLayout(cardManager);
        
        // Set the paramerts for the application's frame
        setLocation(conf.getFrameLocationX(),conf.getFrameLocationY());
        setIconImage(conf.getISnakeIcon());
        setSize(conf.getDesiredFrameDimension());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setMaximumSize(conf.getMaximumFrameDimension());
        setMinimumSize(conf.getMinimumFrameDimension());
        setResizable(true);
        setTitle(conf.getISnakeTitle());

        this.setFocusable(true);
        setLocalPlayerKeyboardInputHandler(new KeyboardInputHandler());
        getLocalPlayerKeyboardInputHandler().setStopKeyboardInputHandler(true);
        this.addKeyListener(getLocalPlayerKeyboardInputHandler());
        
        iSnakeIntroductionPanel isp = new iSnakeIntroductionPanel(conf);
        isp.getNextButton().addActionListener(this);
        gameContentsPanel.add(isp,isp.getPanelName());
        
        MainMenuPanel mmp = new MainMenuPanel(conf);
        gameContentsPanel.add(mmp,mmp.getPanelName());
        MainMenuPanelActionCommandStrings = new String[mmp.menuItemsString.length];
        for(int i=0;i<MainMenuPanelActionCommandStrings.length;i++)   {
            mmp.getMenuItemButtons(i).addActionListener(this);
            MainMenuPanelActionCommandStrings[i] = "from_MainMenuPanel_to_"+mmp.menuItemsCommand[i];
        }
        
        setSmp(new StandaloneModePanel(conf));
        gameContentsPanel.add(getSmp(), getSmp().getPanelName());
        getSmp().getPlayNowButton().addActionListener(this);
        getSmp().getGoBackButton().addActionListener(this);
        
        setGameController(new GameController(conf, getLocalPlayerKeyboardInputHandler()));
        gameContentsPanel.add(getGameController(), getGameController().getPanelName());
        getGameController().getGoBackButton().addActionListener(this);
        getGameController().getGoForDebuging().addActionListener(this);
        
        setGd(new GameDebugPanel(conf, gameController));
        gameContentsPanel.add(getGd(), getGd().getPanelName());
        getGd().getGoBackButton().addActionListener(this);
        
        setMsmp(new MultiplayerServerModePanel(conf));
        gameContentsPanel.add(getMsmp(), getMsmp().getPanelName());
        getMsmp().getPlayNowButton().addActionListener(this);
        getMsmp().getGoBackButton().addActionListener(this);
        
        setMcmp(new MultiplayerClientModePanel(conf));
        gameContentsPanel.add(getMcmp(), getMcmp().getPanelName());
        getMcmp().getPlayNowButton().addActionListener(this);
        getMcmp().getGoBackButton().addActionListener(this);
        
//        gameContentsPanel.add(nextButton,BorderLayout.SOUTH);
        add(gameContentsPanel,BorderLayout.CENTER);
    }

    public void actionPerformed(ActionEvent e)
    {
        if(e.getActionCommand() == "from_iSnakeIntroductionPanel_to_MainMenuPanel") {
            System.out.println("from_iSnakeIntroductionPanel_to_MainMenuPanel");
            cardManager.show(gameContentsPanel,MainMenuPanel.getPanelName());
//            cardManager.next(gameContentsPanel);
        }
        
        /*
         * Action Commands for Main Menu Panel
         */
        if(e.getActionCommand().equals(MainMenuPanelActionCommandStrings[0]))    {
            // command = from_MainMenuPanel_to_multiplayer_server_mode
            System.out.println("command = "+e.getActionCommand());
            cardManager.show(gameContentsPanel,MultiplayerServerModePanel.getPanelName());
        }
        
        if(e.getActionCommand().equals(MainMenuPanelActionCommandStrings[1]))   {
            // command = from_MainMenuPanel_to_multiplayer_client_mode
            System.out.println("command = "+e.getActionCommand());
            cardManager.show(gameContentsPanel,MultiplayerClientModePanel.getPanelName());
        }
        
        if(e.getActionCommand().equals(MainMenuPanelActionCommandStrings[2]))   {
            // command = from_MainMenuPanel_to_standalone_mode
            System.out.println("command = "+e.getActionCommand());
            cardManager.show(gameContentsPanel,StandaloneModePanel.getPanelName());
//            cardManager.next(gameContentsPanel);
        }
        
        if(e.getActionCommand().equals(MainMenuPanelActionCommandStrings[3]))   {
            // command = from_MainMenuPanel_to_about
            System.out.println("command = "+e.getActionCommand());
        }
        
        if(e.getActionCommand().equals(MainMenuPanelActionCommandStrings[4]))   {
            // command = from_MainMenuPanel_to_exit
            System.out.println("command = "+e.getActionCommand());
            dispose();
            System.exit(0);
        }
        
        /*
         * Action Commands for GameController Panel
         */
        if(e.getActionCommand() == "from_GameArea_to_*Mode")  {
            // command = from_GameArea_to_*Mode
            // the return panel is not know and is store in conf.getGameMode
            System.out.println("command = "+e.getActionCommand());
            if(conf.getGameMode().equals(conf.GAME_MULTIPLAYER_CLIENT_MODE))    {
                cardManager.show(gameContentsPanel,MultiplayerClientModePanel.getPanelName());
            }
            else if(conf.getGameMode().equals(conf.GAME_MULTIPLAYER_SERVER_MODE))    {
                cardManager.show(gameContentsPanel,MultiplayerServerModePanel.getPanelName());
            }
            else if(conf.getGameMode().equals(conf.GAME_STANDALONE_MODE))    {
                cardManager.show(gameContentsPanel,StandaloneModePanel.getPanelName());
            }
        }
        if(e.getActionCommand() == "from_GameArea_to_GameDebugPanel")  {
            // command = from_GameArea_to_GameDebugPanel
            System.out.println("command = "+e.getActionCommand());
            cardManager.show(gameContentsPanel,GameDebugPanel.getPanelName());
        }
        
        /*
         * Action Commands for Game Debug Panel
         */
        if(e.getActionCommand() == "from_GameDebugPanel_to_GameAreaPanel")  {
            // command = from_GameDebugPanel_to_GameAreaPanel
            System.out.println("command = "+e.getActionCommand());
            cardManager.show(gameContentsPanel,GameController.getPanelName());
        }
        
        /*
         * Action Commands for Multiplayer Server Mode Panel
         */
        if(e.getActionCommand() == "from_MultiplayerModePanel_to_MainMenu")  {
            // command = from_MultiplayerModePanel_to_MainMenu
            System.out.println("command = "+e.getActionCommand());
            cardManager.show(gameContentsPanel,MainMenuPanel.getPanelName());
        }
        
        if(e.getActionCommand() == "from_MultiplayerServerModePanel_to_GameArea")  {
            // command = from_MultiplayerServerModePanel_to_GameArea
            System.out.println("command = "+e.getActionCommand());

            // Initialize the localSnake and localPlayerPreferences objects
            gameController.setLocalSnake( new Snake(conf,gameController));
            gameController.setLocalPlayerPreferences(new PlayerPreferences());
            gameController.getLocalSnake().setPlayerPreferences(gameController.getLocalPlayerPreferences());

            // set the game mode to Multiplayer Server mode
            conf.setGameMode(conf.GAME_MULTIPLAYER_SERVER_MODE);

            // start the game server
            Integer port = Integer.parseInt(msmp.getServerPortField().getText());

            getGameController().setServerCorePre(new ServerCorePre(port));
            
            conf.setServerPortForClient( Integer.parseInt(msmp.getServerPortField().getText()));
            
            Color snakeColor = (Color) msmp.getPlayerSnakeColorCombo().getSelectedItem();
            
            gameController.getLocalPlayerPreferences().setPlayer_id(new Short("0"));                        // as player_id is not known yet
            gameController.getLocalPlayerPreferences().setName(msmp.getPlayerNameField().getText());        // name as entered by the player
            gameController.getLocalPlayerPreferences().setSnakeColor(snakeColor);
            gameController.getLocalPlayerPreferences().setLocation("Kathmandu");                            // for testing only
            gameController.getLocalPlayerPreferences().setCounty("NEPAL");                                  // for testing only
            gameController.getLocalPlayerPreferences().setHighestScore(new Long("0"));                      // for testing only
            gameController.getLocalPlayerPreferences().setLastPlayerOn(Calendar.getInstance());              // for testing only

            cardManager.show(gameContentsPanel,GameController.getPanelName());
//            System.out.println("game mode= "+conf.getGameMode());
        }
        
        /*
         * Action Commands for Multiplayer Client Mode Panel
         */
        if(e.getActionCommand() == "from_MultiplayerClientModePanel_to_MainMenu")  {
            // command = from_MultiplayerClientModePanel_to_MainMenu
            System.out.println("command = "+e.getActionCommand());
            cardManager.show(gameContentsPanel,MainMenuPanel.getPanelName());
        }
        
        if(e.getActionCommand() == "from_MultiplayerClientModePanel_to_GameArea")  {
            // command = from_MultiplayerClientModePanel_to_GameArea
            System.out.println("command = "+e.getActionCommand());

            // Initialize the localSnake and localPlayerPreferences objects
            gameController.setLocalSnake( new Snake(conf,gameController));
            gameController.setLocalPlayerPreferences(new PlayerPreferences());
            gameController.getLocalSnake().setPlayerPreferences(gameController.getLocalPlayerPreferences());

            // set the game mode to Multiplayer Client mode

            conf.setGameMode(conf.GAME_MULTIPLAYER_CLIENT_MODE);
            conf.setServerNameForClient( mcmp.getServerNameField().getText());
            conf.setServerPortForClient( Integer.parseInt(mcmp.getServerPortField().getText()));
            
            Color snakeColor = (Color) mcmp.getPlayerSnakeColorCombo().getSelectedItem();
            
//            System.out.println("inside iSnakeClient: color= "+snakeColor);
//            System.out.println("inside iSnakeClient: name= "+mcmp.getPlayerNameField().getText());
            
            gameController.getLocalPlayerPreferences().setPlayer_id(new Short("0"));                        // as player_id is not known yet
            gameController.getLocalPlayerPreferences().setName(mcmp.getPlayerNameField().getText());        // name as entered by the player
            gameController.getLocalPlayerPreferences().setSnakeColor(snakeColor);
            gameController.getLocalPlayerPreferences().setLocation("Kathmandu");                            // for testing only
            gameController.getLocalPlayerPreferences().setCounty("NEPAL");                                  // for testing only
            gameController.getLocalPlayerPreferences().setHighestScore(new Long("0"));                      // for testing only
            gameController.getLocalPlayerPreferences().setLastPlayerOn(Calendar.getInstance());              // for testing only

//            System.out.println("Local player information in iSnakeClient "+gameController.getLocalPlayerPreferences().toString());
            
            cardManager.show(gameContentsPanel,GameController.getPanelName());
//            System.out.println("game mode= "+conf.getGameMode());
        }

        /*
         * Action Commands for Stand Alone Mode Panel
         */
        if(e.getActionCommand() == "from_StandaloneModePanel_to_MainMenu")  {
            // command = from_StandaloneModePanel_to_MainMenu
            System.out.println("command = "+e.getActionCommand());
            cardManager.show(gameContentsPanel,MainMenuPanel.getPanelName());
        }
        if(e.getActionCommand() == "from_StandaloneModePanel_to_GameArea")  {
            // command = from_StandaloneModePanel_to_MainMenu
            System.out.println("command = "+e.getActionCommand());

            // set the game mode to Multiplayer Client mode
            conf.setGameMode(conf.GAME_STANDALONE_MODE);

            cardManager.show(gameContentsPanel,GameController.getPanelName());
            System.out.println("game mode= "+conf.getGameMode());
        }

//        System.out.println("e.getActionCommand() = "+e.getActionCommand());
//        System.out.println("MainMenuPanelActionCommandStrings[0] = "+MainMenuPanelActionCommandStrings[0]);
    }
    
    public void showMainMenuPanel()
    {
        System.out.println("comp= "+gameContentsPanel.getComponent(0).toString());
        gameContentsPanel.remove(0);
        gameContentsPanel.repaint();
        MainMenuPanel mmp = new MainMenuPanel(conf);
        gameContentsPanel.add(mmp);
        System.out.println("comp= "+gameContentsPanel.getComponent(0).toString());
        gameContentsPanel.repaint();
    }
    
     private class keyhandler implements KeyListener {
        public void keyTyped(KeyEvent e) {
            System.out.println("key typed");
        }

        public void keyPressed(KeyEvent e) {
            System.out.println("key pressed");
        }

        public void keyReleased(KeyEvent e) {
            System.out.println("key released");
        }
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) 
    {
        iSnakeClient ic = new iSnakeClient();
        ic.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ic.setVisible(true);
    }

    public GameController getGameController() {
        return gameController;
    }

    public void setGameController(GameController gameController) {
        this.gameController = gameController;
    }

    public MultiplayerClientModePanel getMcmp() {
        return mcmp;
    }

    public void setMcmp(MultiplayerClientModePanel mcmp) {
        this.mcmp = mcmp;
    }

    public StandaloneModePanel getSmp() {
        return smp;
    }

    public void setSmp(StandaloneModePanel smp) {
        this.smp = smp;
    }

    public GameDebugPanel getGd() {
        return gd;
    }

    public void setGd(GameDebugPanel gd) {
        this.gd = gd;
    }

    public MultiplayerServerModePanel getMsmp() {
        return msmp;
    }

    public void setMsmp(MultiplayerServerModePanel msmp) {
        this.msmp = msmp;
    }

    public KeyboardInputHandler getLocalPlayerKeyboardInputHandler() {
        return localPlayerKeyboardInputHandler;
    }

    public void setLocalPlayerKeyboardInputHandler(KeyboardInputHandler localPlayerKeyboardInputHandler) {
        this.localPlayerKeyboardInputHandler = localPlayerKeyboardInputHandler;
    }
}